package com.qiangzi.workflow.engine.bpmn.gateway;

import java.util.List;

import org.dom4j.Element;
import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;

import com.qiangzi.workflow.engine.bpmn.base.Edge;
import com.qiangzi.workflow.engine.bpmn.base.ProcessInstance;
import com.qiangzi.workflow.engine.bpmn.base.State;
import com.qiangzi.workflow.engine.bpmn.flow.SequenceFlow;

public class ExclusiveGateway extends Gateway {

	// private String defaultFlow;

	// public String getDefaultFlow() {
	// return defaultFlow;
	// }

	public void parse(Element element) throws Exception {

		super.parse(element);

		Assert.isTrue(null != element, "element is null");

		// default属性是可选的,用来保底
		// Attribute defaultAttribute = element.attribute("default");
		// if (null != defaultAttribute) {
		// String defaultVal = defaultAttribute.getText();
		// if (null != defaultVal && defaultVal.length() > 0) {
		// this.defaultFlow = defaultVal;
		// }
		// }
	}

	protected void deploy() {
		super.deploy();

		// ExclusiveGateway gateway = (ExclusiveGateway) obj;
		// gateway.defaultFlow = this.defaultFlow;

	}

	/**
	 * 排它网关:每个流必须有条件表达式,依次计算表达式的值,碰到第一个true的执行,其它流忽略; 如果都为false,则引擎抛出异常
	 * 
	 * @throws Exception
	 */
	@Override
	public void invoke(ProcessInstance instance, ApplicationContext applicationContext) throws Exception {

		setState(State.INVOKED, instance);
		LOGGER.debug("node {} state -> invoked", getId());

		// 再处理各个边
		List<Edge> edges = this.getOutgoing();

		if (null == edges) {
			return;
		}

		boolean invokeFound = false;

		for (Edge edge : edges) {

			if (edge instanceof SequenceFlow) {

				// 如果前面已经有表达式计算为true的,则后面的都直接设置为忽略
				if (invokeFound) {
					edge.ignore(instance);
					continue;
				}

				edge.invoke(instance, applicationContext);

				// 碰到第一个为true的
				invokeFound = (State.INVOKED == edge.getState());

			} else {
				LOGGER.warn("unknown edge id is {}", edge.getId());
			}
		}

		// 如果全部为忽略,则抛异常
		if (false == invokeFound) {
			throw new Exception("all exclusiveGateway edges expression result -> IGNORED ,id -> " + this.getId());
		}

	}

}
